{
 "cells": [
  {
   "cell_type": "markdown",
   "id": "herbal-ticket",
   "metadata": {},
   "source": [
    "# 使用NAD算法提升模型安全性\n",
    "\n",
    "\n",
    "\n",
    "## 概述\n",
    "\n",
    "本教程介绍MindArmour提供的模型安全防护手段，引导您快速使用MindArmour，为您的AI模型提供一定的安全防护能力。\n",
    "\n",
    "AI算法设计之初普遍未考虑相关的安全威胁，使得AI算法的判断结果容易被恶意攻击者影响，导致AI系统判断失准。攻击者在原始样本处加入人类不易察觉的微小扰动，导致深度学习模型误判，称为对抗样本攻击。MindArmour模型安全提供对抗样本生成、对抗样本检测、模型防御、攻防效果评估等功能，为AI模型安全研究和AI应用安全提供重要支撑。\n",
    "\n",
    "- 对抗样本生成模块支持安全工程师快速高效地生成对抗样本，用于攻击AI模型。\n",
    "\n",
    "- 对抗样本检测、防御模块支持用户检测过滤对抗样本、增强AI模型对于对抗样本的鲁棒性。\n",
    "\n",
    "- 评估模块提供多种指标全面评估对抗样本攻防性能。\n",
    "\n",
    "这里通过图像分类任务上的对抗性攻防，以攻击算法FGSM和防御算法NAD为例，介绍MindArmour在对抗攻防上的使用方法。\n",
    "\n",
    "> 本例面向CPU、GPU、Ascend 910 AI处理器，你可以在这里下载完整的样例代码： https://gitee.com/mindspore/mindarmour/blob/master/examples/model_security/model_defenses/mnist_defense_nad.py"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "continent-gender",
   "metadata": {},
   "source": [
    "## 准备工作\n",
    "\n",
    "本例采用LeNet5网络进行示例，将展示训练后的模型，正常验证的结果如何，使用对抗样本后的验证效果如何，在完成上述情况前，需做如下准备。\n",
    "\n",
    "1. 下载安装跟MindSpore版本对应的MindArmour安装包。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "id": "quick-peace",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "256"
      ]
     },
     "execution_count": 1,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "import os\n",
    "import mindspore\n",
    "\n",
    "version = mindspore.__version__\n",
    "ma_link = \"https://ms-release.obs.cn-north-4.myhuaweicloud.com/{0}/MindArmour/x86_64/mindarmour-{0}-cp37-cp37m-linux_x86_64.whl\".format(version)\n",
    "os.system(\"pip install {}\".format(ma_link))"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "fitting-strip",
   "metadata": {},
   "source": [
    "2. 准备MNIST数据集。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "naughty-daniel",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "./datasets/MNIST_Data\n",
      "├── test\n",
      "│   ├── t10k-images-idx3-ubyte\n",
      "│   └── t10k-labels-idx1-ubyte\n",
      "└── train\n",
      "    ├── train-images-idx3-ubyte\n",
      "    └── train-labels-idx1-ubyte\n",
      "\n",
      "2 directories, 4 files\n"
     ]
    }
   ],
   "source": [
    "!mkdir -p ./datasets/MNIST_Data/train ./datasets/MNIST_Data/test\n",
    "!wget -NP ./datasets/MNIST_Data/train https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/train-labels-idx1-ubyte\n",
    "!wget -NP ./datasets/MNIST_Data/train https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/train-images-idx3-ubyte\n",
    "!wget -NP ./datasets/MNIST_Data/test https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/t10k-labels-idx1-ubyte\n",
    "!wget -NP ./datasets/MNIST_Data/test https://mindspore-website.obs.myhuaweicloud.com/notebook/datasets/mnist/t10k-images-idx3-ubyte\n",
    "!tree ./datasets/MNIST_Data"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "handmade-cookie",
   "metadata": {},
   "source": [
    "## 建立被攻击模型\n",
    "\n",
    "以MNIST为示范数据集，自定义的简单模型作为被攻击模型。\n",
    "\n",
    "### 引入相关包"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "surprised-jonathan",
   "metadata": {},
   "outputs": [],
   "source": [
    "import os\n",
    "import numpy as np\n",
    "from scipy.special import softmax\n",
    "\n",
    "from mindspore import dataset as ds\n",
    "from mindspore import dtype as mstype\n",
    "import mindspore.dataset.vision.c_transforms as CV\n",
    "import mindspore.dataset.transforms.c_transforms as C\n",
    "from mindspore.dataset.vision import Inter\n",
    "import mindspore.nn as nn\n",
    "from mindspore.nn import SoftmaxCrossEntropyWithLogits\n",
    "from mindspore.common.initializer import TruncatedNormal\n",
    "from mindspore import Model, Tensor, context\n",
    "from mindspore.train.callback import LossMonitor\n",
    "\n",
    "from mindarmour.adv_robustness.attacks import FastGradientSignMethod\n",
    "from mindarmour.utils.logger import LogUtil\n",
    "from mindarmour.adv_robustness.evaluations import AttackEvaluate\n",
    "\n",
    "context.set_context(mode=context.GRAPH_MODE, device_target=\"GPU\")\n",
    "\n",
    "LOGGER = LogUtil.get_instance()\n",
    "LOGGER.set_level(\"INFO\")\n",
    "TAG = 'demo'"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "linear-northwest",
   "metadata": {},
   "source": [
    "### 加载数据集\n",
    "\n",
    "利用MindSpore的dataset提供的MnistDataset接口加载MNIST数据集。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "bacterial-absolute",
   "metadata": {},
   "outputs": [],
   "source": [
    "# generate dataset for train of test\n",
    "def generate_mnist_dataset(data_path, batch_size=32, repeat_size=1,\n",
    "                           num_parallel_workers=1, index=True):\n",
    "    \"\"\"\n",
    "    create dataset for training or testing\n",
    "    \"\"\"\n",
    "    # define dataset\n",
    "    ds1 = ds.MnistDataset(data_path)\n",
    "\n",
    "    # define operation parameters\n",
    "    resize_height, resize_width = 32, 32\n",
    "    rescale = 1.0 / 255.0\n",
    "    shift = 0.0\n",
    "\n",
    "    # define map operations\n",
    "    resize_op = CV.Resize((resize_height, resize_width),\n",
    "                          interpolation=Inter.LINEAR)\n",
    "    rescale_op = CV.Rescale(rescale, shift)\n",
    "    hwc2chw_op = CV.HWC2CHW()\n",
    "    type_cast_op = C.TypeCast(mstype.int32)\n",
    "\n",
    "    # apply map operations on images\n",
    "    if not index:\n",
    "        one_hot_enco = C.OneHot(10)\n",
    "        ds1 = ds1.map(operations=one_hot_enco, input_columns=\"label\",\n",
    "                      num_parallel_workers=num_parallel_workers)\n",
    "        type_cast_op = C.TypeCast(mstype.float32)\n",
    "        \n",
    "    ds1 = ds1.map(operations=type_cast_op, input_columns=\"label\",\n",
    "                  num_parallel_workers=num_parallel_workers)\n",
    "    ds1 = ds1.map(operations=resize_op, input_columns=\"image\",\n",
    "                  num_parallel_workers=num_parallel_workers)\n",
    "    ds1 = ds1.map(operations=rescale_op, input_columns=\"image\",\n",
    "                  num_parallel_workers=num_parallel_workers)\n",
    "    ds1 = ds1.map(operations=hwc2chw_op, input_columns=\"image\",\n",
    "                  num_parallel_workers=num_parallel_workers)\n",
    "\n",
    "    # apply DatasetOps\n",
    "    buffer_size = 10000\n",
    "    ds1 = ds1.shuffle(buffer_size=buffer_size)\n",
    "    ds1 = ds1.batch(batch_size, drop_remainder=True)\n",
    "    ds1 = ds1.repeat(repeat_size)\n",
    "\n",
    "    return ds1"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "becoming-rebel",
   "metadata": {},
   "source": [
    "### 建立模型\n",
    "\n",
    "这里以LeNet模型为例，您也可以建立训练自己的模型。\n",
    "\n",
    "1. 定义LeNet模型网络。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "affected-assist",
   "metadata": {},
   "outputs": [],
   "source": [
    "import mindspore.nn as nn\n",
    "from mindspore.common.initializer import Normal\n",
    "\n",
    "class LeNet5(nn.Cell):\n",
    "    \"\"\"Lenet network structure.\"\"\"\n",
    "    # define the operator required\n",
    "    def __init__(self, num_class=10, num_channel=1):\n",
    "        super(LeNet5, self).__init__()\n",
    "        self.conv1 = nn.Conv2d(num_channel, 6, 5, pad_mode='valid')\n",
    "        self.conv2 = nn.Conv2d(6, 16, 5, pad_mode='valid')\n",
    "        self.fc1 = nn.Dense(16 * 5 * 5, 120, weight_init=Normal(0.02))\n",
    "        self.fc2 = nn.Dense(120, 84, weight_init=Normal(0.02))\n",
    "        self.fc3 = nn.Dense(84, num_class, weight_init=Normal(0.02))\n",
    "        self.relu = nn.ReLU()\n",
    "        self.max_pool2d = nn.MaxPool2d(kernel_size=2, stride=2)\n",
    "        self.flatten = nn.Flatten()\n",
    "\n",
    "    # use the preceding operators to construct networks\n",
    "    def construct(self, x):\n",
    "        x = self.max_pool2d(self.relu(self.conv1(x)))\n",
    "        x = self.max_pool2d(self.relu(self.conv2(x)))\n",
    "        x = self.flatten(x)\n",
    "        x = self.relu(self.fc1(x))\n",
    "        x = self.relu(self.fc2(x))\n",
    "        x = self.fc3(x)\n",
    "        return x"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "stupid-invalid",
   "metadata": {},
   "source": [
    "2. 训练LeNet模型。利用上面定义的数据加载函数`generate_mnist_dataset`载入数据。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "vulnerable-pierce",
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "epoch: 1 step: 1875, loss is 2.3040888\n",
      "epoch: 2 step: 1875, loss is 0.29309553\n",
      "epoch: 3 step: 1875, loss is 0.19545117\n"
     ]
    }
   ],
   "source": [
    "mnist_path = \"./datasets/MNIST_Data/\"\n",
    "batch_size = 32\n",
    "# train original model\n",
    "ds_train = generate_mnist_dataset(os.path.join(mnist_path, \"train\"),\n",
    "                                  batch_size=batch_size, repeat_size=1,\n",
    "                                  index=False)\n",
    "net = LeNet5()\n",
    "loss = SoftmaxCrossEntropyWithLogits(sparse=False, reduction=\"mean\")\n",
    "opt = nn.Momentum(net.trainable_params(), 0.01, 0.9)\n",
    "model = Model(net, loss, opt, metrics=None)\n",
    "model.train(3, ds_train, callbacks=[LossMonitor(1875)],\n",
    "            dataset_sink_mode=False)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "simplified-hunter",
   "metadata": {},
   "source": [
    "3. 测试模型"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "engaging-corner",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:15,249 [<ipython-input-7-04c3ee7c4eeb>:24] [demo] prediction accuracy before attacking is : 0.9779647435897436\n"
     ]
    }
   ],
   "source": [
    "# prediction accuracy before attack\n",
    "\n",
    "# get test data\n",
    "ds_test = generate_mnist_dataset(os.path.join(mnist_path, \"test\"),\n",
    "                                 batch_size=batch_size, repeat_size=1,\n",
    "                                 index=False)\n",
    "inputs = []\n",
    "labels = []\n",
    "for data in ds_test.create_tuple_iterator():\n",
    "    inputs.append(data[0].asnumpy().astype(np.float32))\n",
    "    labels.append(data[1].asnumpy())\n",
    "\n",
    "test_inputs = np.concatenate(inputs)\n",
    "test_labels = np.concatenate(labels)\n",
    "\n",
    "def get_net_acc(network, inputs_data, labels):\n",
    "    network.set_train(False)\n",
    "    test_logits = net(Tensor(inputs_data)).asnumpy()\n",
    "    tmp = np.argmax(test_logits, axis=1) == np.argmax(labels, axis=1)\n",
    "    accuracy = np.mean(tmp)\n",
    "    return accuracy\n",
    "\n",
    "accuracy = get_net_acc(net, test_inputs, test_labels)\n",
    "LOGGER.info(TAG, 'prediction accuracy before attacking is : %s', accuracy)"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "improved-composition",
   "metadata": {},
   "source": [
    "测试结果中分类精度达到了97%以上。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "secondary-headset",
   "metadata": {},
   "source": [
    "## 对抗性攻击\n",
    "\n",
    "在进行对抗性攻击前，选取32张图片查看，没有攻击前的图片展示的效果如何。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "genetic-reservoir",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 32 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "import matplotlib.pyplot as plt\n",
    "\n",
    "count = 1\n",
    "%matplotlib inline\n",
    "for i in test_inputs[:32]:\n",
    "    plt.subplot(4, 8, count)\n",
    "    plt.imshow(np.squeeze(i), cmap='gray', interpolation='nearest')\n",
    "    plt.xticks([])\n",
    "    plt.axis(\"off\")\n",
    "    count += 1\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "three-printer",
   "metadata": {},
   "source": [
    "调用MindArmour提供的FGSM接口（FastGradientSignMethod），对验证的图片数据进行对抗性攻击。\n",
    "\n",
    "查看之前选取的32张图片，对抗性攻击后，图片产生了什么变化。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "id": "superb-bearing",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 432x288 with 32 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# attacking\n",
    "# get adv data\n",
    "attack = FastGradientSignMethod(net, eps=0.3, loss_fn=loss)\n",
    "adv_data = attack.batch_generate(test_inputs, test_labels)\n",
    "\n",
    "count = 1\n",
    "%matplotlib inline\n",
    "for i in adv_data[:32]:\n",
    "    plt.subplot(4, 8, count)\n",
    "    plt.imshow(np.squeeze(i), cmap='gray', interpolation='nearest')\n",
    "    plt.xticks([])\n",
    "    count += 1\n",
    "\n",
    "plt.axis(\"off\")\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "earlier-amplifier",
   "metadata": {},
   "source": [
    "受到攻击后，图片出现了很多的类似水印的背景，但是在视觉上还是能明显地分辨出来图片是什么，但是对于模型来说，可能不一定。\n",
    "\n",
    "接下来，验证模型在攻击后的图片分类能力。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "id": "greater-prophet",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:17,892 [<ipython-input-10-b5401939add9>:6] [demo] prediction accuracy after attacking is : 0.045072115384615384\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:17,926 [<ipython-input-10-b5401939add9>:12] [demo] mis-classification rate of adversaries is : 0.9549278846153846\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:17,926 [<ipython-input-10-b5401939add9>:14] [demo] The average confidence of adversarial class is : 0.70117253\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:17,927 [<ipython-input-10-b5401939add9>:16] [demo] The average confidence of true class is : 0.04269705\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:18,667 [<ipython-input-10-b5401939add9>:19] [demo] The average distance (l0, l2, linf) between original samples and adversarial samples are: (2.2191764481915106, 0.5356972896720278, 0.3000000376345752)\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:20,650 [<ipython-input-10-b5401939add9>:22] [demo] The average structural similarity between original samples and adversarial samples are: 0.5092086321477988\n"
     ]
    }
   ],
   "source": [
    "# get accuracy of adv data on original model\n",
    "adv_logits = net(Tensor(adv_data)).asnumpy()\n",
    "adv_proba = softmax(adv_logits, axis=1)\n",
    "tmp = np.argmax(adv_proba, axis=1) == np.argmax(test_labels, axis=1)\n",
    "accuracy_adv = np.mean(tmp)\n",
    "LOGGER.info(TAG, 'prediction accuracy after attacking is : %s', accuracy_adv)\n",
    "attack_evaluate = AttackEvaluate(test_inputs.transpose(0, 2, 3, 1),\n",
    "                                 test_labels,\n",
    "                                 adv_data.transpose(0, 2, 3, 1),\n",
    "                                 adv_proba)\n",
    "LOGGER.info(TAG, 'mis-classification rate of adversaries is : %s',\n",
    "            attack_evaluate.mis_classification_rate())\n",
    "LOGGER.info(TAG, 'The average confidence of adversarial class is : %s',\n",
    "            attack_evaluate.avg_conf_adv_class())\n",
    "LOGGER.info(TAG, 'The average confidence of true class is : %s',\n",
    "            attack_evaluate.avg_conf_true_class())\n",
    "LOGGER.info(TAG, 'The average distance (l0, l2, linf) between original '\n",
    "            'samples and adversarial samples are: %s',\n",
    "            attack_evaluate.avg_lp_distance())\n",
    "LOGGER.info(TAG, 'The average structural similarity between original '\n",
    "            'samples and adversarial samples are: %s',\n",
    "            attack_evaluate.avg_ssim())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "stainless-blogger",
   "metadata": {},
   "source": [
    "对模型进行FGSM无目标攻击后：\n",
    "\n",
    "- 模型精度由97%以上降到不足10%；\n",
    "\n",
    "- 误分类率超过90%，成功攻击的对抗样本的预测类别的平均置信度（ACAC）为 0.70117253；\n",
    "\n",
    "- 成功攻击的对抗样本的真实类别的平均置信度（ACTC）为 0.04269705；\n",
    "\n",
    "- 同时给出了生成的对抗样本与原始样本的零范数距离、二范数距离和无穷范数距离，平均每个对抗样本与原始样本间的结构相似性为0.5092086；\n",
    "\n",
    "- 平均每生成一张对抗样本所需时间为0.003125s。\n",
    "\n",
    "FGSM无目标攻击后生成的对抗样本。从视觉角度而言，几乎没有明显变化，但是均成功误导了模型，使模型将其误分类为其他非正确类别。"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "private-shoulder",
   "metadata": {},
   "source": [
    "## 对抗性防御\n",
    "\n",
    "NaturalAdversarialDefense（NAD）是一种简单有效的对抗样本防御方法，使用对抗训练的方式，在模型训练的过程中构建对抗样本，并将对抗样本与原始样本混合，一起训练模型。随着训练次数的增加，模型在训练的过程中提升对于对抗样本的鲁棒性。NAD算法使用FGSM作为攻击算法，构建对抗样本。\n",
    "\n",
    "### 防御实现\n",
    "\n",
    "调用MindArmour提供的NAD防御接口（NaturalAdversarialDefense）。"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "id": "animal-resident",
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:31,896 [<ipython-input-11-2b02004977b6>:15] [demo] accuracy of TEST data on defensed model is : 0.9793669871794872\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:32,001 [<ipython-input-11-2b02004977b6>:29] [demo] accuracy of adv data on defensed model is : 0.7190504807692307\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:32,002 [<ipython-input-11-2b02004977b6>:31] [demo] defense mis-classification rate of adversaries is : 0.2809495192307692\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:32,003 [<ipython-input-11-2b02004977b6>:33] [demo] The average confidence of adversarial class is : 0.5715536\n",
      "[INFO] MA(22790:140157538080576,MainProcess):2021-04-07 15:35:32,004 [<ipython-input-11-2b02004977b6>:35] [demo] The average confidence of true class is : 0.16227658\n"
     ]
    }
   ],
   "source": [
    "from mindarmour.adv_robustness.defenses import NaturalAdversarialDefense\n",
    "\n",
    "# defense\n",
    "net.set_train()\n",
    "nad = NaturalAdversarialDefense(net, loss_fn=loss, optimizer=opt,\n",
    "                                bounds=(0.0, 1.0), eps=0.3)\n",
    "nad.batch_defense(test_inputs, test_labels, batch_size=32, epochs=10)\n",
    "\n",
    "# get accuracy of test data on defensed model\n",
    "net.set_train(False)\n",
    "test_logits = net(Tensor(test_inputs)).asnumpy()\n",
    "\n",
    "tmp = np.argmax(test_logits, axis=1) == np.argmax(test_labels, axis=1)\n",
    "accuracy = np.mean(tmp)\n",
    "LOGGER.info(TAG, 'accuracy of TEST data on defensed model is : %s', accuracy)\n",
    "\n",
    "# get accuracy of adv data on defensed model\n",
    "adv_logits = net(Tensor(adv_data)).asnumpy()\n",
    "adv_proba = softmax(adv_logits, axis=1)\n",
    "tmp = np.argmax(adv_proba, axis=1) == np.argmax(test_labels, axis=1)\n",
    "accuracy_adv = np.mean(tmp)\n",
    "\n",
    "attack_evaluate = AttackEvaluate(test_inputs.transpose(0, 2, 3, 1),\n",
    "                                 test_labels,\n",
    "                                 adv_data.transpose(0, 2, 3, 1),\n",
    "                                 adv_proba)\n",
    "\n",
    "LOGGER.info(TAG, 'accuracy of adv data on defensed model is : %s',\n",
    "            np.mean(accuracy_adv))\n",
    "LOGGER.info(TAG, 'defense mis-classification rate of adversaries is : %s',\n",
    "            attack_evaluate.mis_classification_rate())\n",
    "LOGGER.info(TAG, 'The average confidence of adversarial class is : %s',\n",
    "            attack_evaluate.avg_conf_adv_class())\n",
    "LOGGER.info(TAG, 'The average confidence of true class is : %s',\n",
    "            attack_evaluate.avg_conf_true_class())"
   ]
  },
  {
   "cell_type": "markdown",
   "id": "sonic-violence",
   "metadata": {},
   "source": [
    "### 防御效果\n",
    "\n",
    "使用NAD进行对抗样本防御后，模型对于对抗样本的误分类率从90%以上降至不足30%，模型有效地防御了对抗样本。同时，模型对于原来测试数据集的分类精度达97%。"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "MindSpore-1.1.1",
   "language": "python",
   "name": "mindspore-1.1.1"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
